#pragma warning(disable: 4005)

#include "Win32Graphics.h"
#include "Win32DebugDisplay.h"
#include "Win32Input.h"

#include "DirectX\Device.h"
#include "DirectX\Camera.h"
#include "DirectX\Color.h"
#include "DirectX\Utility.h"
#include "DirectX\Text.h"
#include "DirectX\RenderTexture.h"
#include "DirectX\ShaderResourceManager.h"
#include "DirectX\MaterialResourceManager.h"
#include "DirectX\ModelResourceManager.h"
#include "DirectX\TextureResourceManager.h"

#include "NeroCore\NMemoryManager.h"
#include "NeroGame\NGame.h"
#include "NeroGame\NWorld.h"

using namespace System;
using namespace Graphics;

RTTI_DEFINITIONS(Win32Graphics)

Win32Graphics::Win32Graphics()
	:NGraphics(),
	 mDevice(NULL),
	 mSceneCamera(NULL),
	 mDebugDisplay(NULL)
{
}

Win32Graphics::~Win32Graphics(void)
{
	Deinitialize();
}

void Win32Graphics::Initialize(Engine::NPlatform* owner,HINSTANCE instance, int showCommand)
{
	//
	mDevice = MY_NEW(Memory::HID_Rendering,"Device") D3DDevice(owner);
	mDevice->Initialize(instance, showCommand);

	Graphics::ShaderResourceManager::Initialize();
	Graphics::TextureResourceManager::Initialize();
	Graphics::MaterialResourceManager::Initialize();
	Graphics::ModelResourceManager::Initialize();
	
	mSceneCamera = MY_NEW(Memory::HID_Rendering, "Camera") Camera();
	mSceneCamera->SetPosition(NVector3(0.0f, 0.0f, -10.0f));
	mSceneCamera->Update(0.0f);

	//
	mBaseViewMatrix = Utility::NeroToDXD(mSceneCamera->GetViewMatrix());

	mDebugDisplay = MY_NEW(Memory::HID_Engine, "Win32DebugDiplay") Win32DebugDisplay();
	mDebugDisplay->Initialize(mBaseViewMatrix);

	//
	owner->SetCamera(mSceneCamera);
}

void Win32Graphics::Deinitialize()
{
	Graphics::ShaderResourceManager::Deinitialize();
	Graphics::TextureResourceManager::Deinitialize();
	Graphics::MaterialResourceManager::Deinitialize();
	Graphics::ModelResourceManager::Deinitialize();

	if(mSceneCamera)
	{
		MY_DELETE(mSceneCamera);
		mSceneCamera = NULL;
	}

	if(mDebugDisplay)
	{
		MY_DELETE(mDebugDisplay);
		mDebugDisplay = NULL;
	}

	if(mDevice)
	{
		MY_DELETE(mDevice);
		mDevice = NULL;
	}
}

void Win32Graphics::Render()
{
	GetGame()->PreRender();

	mDevice->BeginRender();

	RenderScene();

	mDevice->EndRender();

	GetGame()->PostRender();
}

void Win32Graphics::Update(float deltaTime)
{
	NGraphics::Update(deltaTime);

	if(mDevice)
	{
		mDevice->Update(deltaTime);
	}
	if(mSceneCamera)
	{
		mSceneCamera->Update(deltaTime);
	}
	if(mDebugDisplay)
	{
		mDebugDisplay->Update(deltaTime);
	}
}

bool Win32Graphics::RenderToTexture(RenderTexture* texture, float rotation)
{
	UNREFERENCED_PARAMETER(rotation);

	texture->SetRenderTarget();

	texture->ClearRenderTarget(Colors::Black);

	RenderScene();

	mDevice->SetBackBufferRenderTarget();

	return true;
}

void Win32Graphics::RenderScene()
{
	GetGame()->Render();

	if(mDebugDisplay)
	{
		mDebugDisplay->Render();
	}
}

Graphics::D3DDevice* Win32Graphics::GetDevice()
{
	return mDevice;
}

void Win32Graphics::ProcessInput()
{
	if(GetInput()->IsKeyDown(VK_F11))
	{
		mDevice->ToggleFullScreen();
	}
}